#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
/*
    #include <unistd.h>
    ssize_t read(int fd, void *buf, size_t count);
    功能：从fd文件描述符引用的文件中读取count的字符放入buf对应的容器中
    参数1：已经打开文件对应的文件描述符
    参数2：容器的起始地址
    参数3：要读取的字符个数
    返回值：成功返回读取的字符个数，这个个数可能会小于count的值，失败返回-1并置位错误码

    #include <unistd.h>
    ssize_t write(int fd, const void *buf, size_t count);
    功能：将buf容器中的count个数据，写入到fd引用的文件中
    参数1：已经打开的文件的文件描述符
    参数2：要写入的数据的起始地址
    参数3：要写入数据的个数
    返回值：成功返回写入的字符个数，这个个数可能小于count，失败返回-1并置位错误码

    注：
    read读入时候本身是没有'\0'的('\n'是有的,因为文件换行也是这个字符)
    '\0'是编程语言中字符串的结束标志
    而fgets会在读入时候在缓冲区加入'\0'，这就是为什么读取字节数减一原因
    fputs会在写入时候以缓冲区中的'\0'为结束标志
*/
int main(int argc, const char *argv[])
{
    // 1、定义文件描述符，对于文件IO而言，句柄就是文件描述符
    int fd = -1;
    // 以只读的形式创建文件，如果文件不存在则创建文件
    // 如果创建文件时没有给权限，则该文件的权限是随机权限
    // 如果创建文件时，给定了文件的权限，则文件最终的权限是 给定的 mode&~umask
    if ((fd = open("./tt.txt", O_WRONLY | O_CREAT, 0644)) == -1)
    {
        perror("open error");
        return -1;
    }
    printf("open success fd = %d\n", fd); // 3,由于0、1、2已经被使用，所以该数为3
    // 对数据进行读写操作
    char wbuf[128] = "hello world";
    // 将上述字符串写入文件中
    write(fd, wbuf, strlen(wbuf));

    close(fd); // 关闭fd引用的文件

    // 再次以只读的形式打开文件，此时参数2中不需要使用O_CREAT，那么第三个参数也不需要了
    if ((fd = open("./tt.txt", O_RDONLY)) == -1)
    {
        perror("open error");
        return -1;
    }
    printf("open success fd = %d\n", fd); // 3
    // 定义接收数据容器
    char rbuf[5] = "";
    int res = read(fd, rbuf, sizeof(rbuf));
    write(1, rbuf, res);
    // 从文件中读取数据放入rbuf中
    // 向1号文件描述符中写入数据，之前读取多少，现在写入多少
    // 关闭文件
    close(fd);
    return 0;
}